package ru.ifmo.thesis.gp;

import java.util.ArrayList;
import java.util.List;

import org.jgap.BaseGeneticOperator;
import org.jgap.Chromosome;
import org.jgap.Configuration;
import org.jgap.Gene;
import org.jgap.InvalidConfigurationException;
import org.jgap.Population;
import org.jgap.RandomGenerator;

import ru.ifmo.thesis.domain.Job;
import ru.ifmo.thesis.domain.Worker;
import ru.ifmo.thesis.quantities.Percent;
import ru.ifmo.thesis.util.Algorithms;

public class RIGAOperator extends BaseGeneticOperator {

	private static final long serialVersionUID = 1L;
	private final Percent substitutionProbability;

	public RIGAOperator(Configuration aConfiguration, Percent substitutionProbability)
			throws InvalidConfigurationException {
		super(aConfiguration);
		this.substitutionProbability = substitutionProbability;
	}


	@Override
	public void operate(Population aPopulation, List chromosomes) {
		RandomGenerator rg = getConfiguration().getRandomGenerator();
		List<Chromosome> chromoCopy = Algorithms.deepCopyPopulation(
				(List<Chromosome>) aPopulation.getChromosomes());
		
		List<Worker> workers = new ArrayList<Worker>();
		List<Job> jobs = new ArrayList<Job>();
		for (Gene g : (Gene[])chromoCopy.get(0).getGenes()) {
			WorkPlanGene gene = (WorkPlanGene) g;
			workers.add(gene.getAssociatedWorker());
			jobs.addAll((List<Job>)gene.getInternalValue());
		}
		
		for (Chromosome c : chromoCopy) {
			if (rg.nextDouble() < substitutionProbability.value()) {
				try {
					chromosomes.add(Algorithms.createRandomChromosome(
							this.getConfiguration(), workers, jobs));
					aPopulation.getChromosomes().remove(c);
				} catch (InvalidConfigurationException e) {
					throw new RuntimeException(e);
				}
			}
		}		
	}

	@Override
	public int compareTo(Object o) {
		return 0;
	}
}
